import type { Action } from 'element-plus'
import type { Tree } from './type'
import type { SaveOrUpdatePointParams } from '@/types'
import * as pointApi from '@/api/modules/point'

export function useTreeFilter(
  key: string = 'label',
  callback?: (val: string) => any,
) {
  const filterTextInput = ref<string>('')

  const filterNode = (value: string, data: any) => {
    if (!value)
      return true
    return data[key].includes(value)
  }

  watch(
    () => filterTextInput.value,
    (val: string) => {
      callback?.(val)
    },
  )
  return {
    filterTextInput,

    filterNode,
  }
}

export function usePoint() {
  const { vLoading, withLoading } = useDefineLoading()
  const treeData = shallowRef<any[]>([])
  const defaultTreeExpandKeys = ref<number[]>([])

  const getTreeData = async () => {
    const { data: res } = await withLoading(pointApi.loadRoleEnergyUnit)()
    if (!res || !res.list) {
      treeData.value = []
      defaultTreeExpandKeys.value = []
      return
    }
    treeData.value = res.list || []
    if (res.pointIdList === null) {
      defaultTreeExpandKeys.value = findAllIdFromTree(res.list, [])
    }
    else {
      defaultTreeExpandKeys.value = (res.pointIdList || []).map((v: string) => Number(v))
    }
  }

  function findAllIdFromTree(tree: any[], ids: number[]) {
    tree.forEach((item) => {
      ids.push(item.id)
      if (item.children && item.children.length > 0) {
        findAllIdFromTree(item.children, ids)
      }
    })
    return ids
  }

  const clickAppend = async (data: Tree) => {
    const _res = await ElMessageBox.prompt(
      '输入用能单元名称',
      '新增用能单元',
      {
        inputPattern: /^\S{2,20}$/,
        inputErrorMessage: '输入2~20个字符',
      },
    ).catch(() => {})
    if (!_res)
      return
    const { value } = _res
    const params: SaveOrUpdatePointParams = {
      pointName: value,
      parentId: data.id,
    }
    saveOrUpdatePoint(params)
  }
  const clickParentAppend = async () => {
    const _res = await ElMessageBox.prompt(
      '输入用能名称',
      '新增用能',
      {
        inputPattern: /^\S{2,20}$/,
        inputErrorMessage: '输入2~20个字符',
      },
    ).catch(() => {})
    if (!_res)
      return
    const { value } = _res
    const params = {
      // pointCode: Date.now().toString(),
      pointName: value,
    }
    saveOrUpdatePoint(params)
  }
  async function saveOrUpdatePoint(
    params: SaveOrUpdatePointParams,
  ) {
    const { code } = await pointApi.saveOrUpdatePoint(
      params,
    )
    if (code !== 200) {
      ElMessage.info('新增&修改失败！')
      return
    }
    ElMessage.success('新增&修改成功！')
    getTreeData()
  }
  const clickRemove = async (data: Tree) => {
    const res: Action = await ElMessageBox.confirm(
      '确定要删除该条数据吗？',
      '操作提示',
    ).catch(e => e)
    if (res !== 'confirm')
      return
    const { code } = await pointApi.deletePoint(data.id)
    if (code !== 200) {
      ElMessage.info('删除失败，请稍后再试！')
      return
    }

    getTreeData()
    ElMessage.success('删除成功')
  }
  const clickUpdate = async (data: Tree) => {
    const _res = await ElMessageBox.prompt(
      '输入用能单元名称',
      '修改用能单元',
      {
        inputValue: data.pointName ?? '',
        inputPattern: /^\S{2,20}$/,
        inputErrorMessage: '输入2~20个字符',
      },
    ).catch(() => {})
    if (!_res)
      return
    const { value } = _res
    const params: SaveOrUpdatePointParams = {
      pointName: value,
      parentId: data.parentId,
      id: data.id,
    }
    saveOrUpdatePoint(params)
  }

  function prevable(node: any) {
    const curId = node.id
    const parent = node.parent
    const childNodes = parent.childNodes || []
    return childNodes[0]?.id !== curId
  }
  function nextable(node: any) {
    const curId = node.id
    const parent = node.parent
    const childNodes = parent.childNodes || []
    return childNodes[childNodes.length - 1]?.id !== curId
  }

  function findPrevId(node: any) {
    const curId = node.id
    const parent = node.parent
    const childNodes = parent.childNodes || []
    const curIndex = childNodes.findIndex(
      (item: any) => item.id === curId,
    )
    return childNodes[curIndex - 1]?.data?.id
  }
  function findNextId(node: any) {
    const curId = node.id
    const parent = node.parent
    const childNodes = parent.childNodes || []
    const curIndex = childNodes.findIndex(
      (item: any) => item.id === curId,
    )
    return childNodes[curIndex + 1]?.data?.id
  }

  async function clickMovePrev(node: any) {
    const curId = node.data?.id
    const targetId = findPrevId(node)
    if (curId && targetId) {
      await pointApi.sortEnergyUnit(curId, targetId)
      await getTreeData()
    }
    else {
      console.warn(
        `[clickMovePrev] cur: ${curId}, target: ${targetId}`,
      )
    }
  }
  async function clickMoveNext(node: any) {
    const curId = node.data?.id
    const targetId = findNextId(node)
    if (curId && targetId) {
      await pointApi.sortEnergyUnit(curId, targetId)
      await getTreeData()
    }
    else {
      console.warn(
        `[clickMoveNext] cur: ${curId}, target: ${targetId}`,
      )
    }
  }

  return {
    treeData,
    defaultTreeExpandKeys,
    vLoading,

    clickAppend,
    clickParentAppend,
    clickUpdate,
    clickRemove,
    getTreeData,
    clickMoveNext,
    clickMovePrev,
    prevable,
    nextable,
  }
}
